package org.helsoft.mojo.api;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.codehaus.gmaven.mojo.GroovyMojo;

public abstract class PDEMojo extends GroovyMojo {
	/**
	 * The maven project.
	 * 
	 * @parameter expression="${project}"
	 * @required
	 */
	 MavenProject project;

	/**
	 * Manifest.
	 * 
	 * @parameter default-value="${project.basedir}/META-INF/MANIFEST.MF"
	 * @required
	 */
	String manifestLocation;

	/**
	 * Build properties.
	 * 
	 * @parameter default-value="${project.basedir}/build.properties"
	 */
	String buildPropertiesFile;

	/**
	 * Build configuration could be use to override the
	 * <code>buildPropertiesFile</code>.
	 * 
	 * @parameter
	 */
	Properties buildProperties;

	/**
	 * If this variable is set the resolved bundle will be copied to this
	 * directory pointed by this variable, and the systemPath of the
	 * dependencies will be set according to this location. Be aware if you use
	 * an SCM such as svn, cvs or others to not commit this directory, which
	 * must be delete by the clean goal. The path provided by this variable its
	 * relative to the project basedir.
	 * 
	 * @parameter expression="${tempLibrariesLocation}"
	 */
	String tempLibrariesLocation;

	/**
	 * The plugin descriptor from the manifest location.
	 */
	PluginDescriptor descriptor;

	/**
	 * The file where the pde pom is generated.
	 * 
	 * @parameter expression="${pde.pom}" default-value="pde-pom.xml"
	 */
	File pdePOMFile;
	
	/**
	 * 
	 * @return The build properties
	 * @throws MojoExecutionException
	 */
	public final Properties getBuildProperties() throws MojoExecutionException {
		if (buildProperties == null) {
			Properties props = null;

			File file = buildPropertiesFile != null ? new File(
					buildPropertiesFile) : null;

			if (file != null && file.isFile()) {
				InputStream input = null;
				try {
					input = new FileInputStream(file);
					props = new Properties();
					props.load(input);
				} catch (IOException e) {
					throw new MojoExecutionException(
							"No build.properties file has been found");
				} finally {
					if (input != null) {
						try {
							input.close();
						} catch (IOException e) {
							// Ignore
						}
					}
				}
			}

			buildProperties = props;
		}

		return buildProperties;
	}

	/**
	 * 
	 * @return The descriptor of the plugin currently built
	 * @throws MojoFailureException
	 * @throws MojoExecutionException 
	 */
	public final PluginDescriptor getPluginDescriptor()
			throws MojoFailureException, MojoExecutionException {
		if (descriptor == null) {
			try {
				descriptor = PluginDescriptor.fromManifest(new File(
						manifestLocation));
			} catch (IOException e) {
				fail("Error opening the manifest at '"
						+ manifestLocation + "'", e);
			}
		}
		return descriptor;
	}

	/**
	 * 
	 * @return
	 */
	public final File getLibrairiesLocation() {
		File result = null;
		try {
			if (tempLibrariesLocation == null
					|| tempLibrariesLocation.trim().isEmpty()
					|| project
							.getBasedir()
							.getCanonicalPath()
							.equals(new File(project.getBasedir(),
									tempLibrariesLocation).getCanonicalPath())) 
			{
				result = null;
			}  else {
				result = new File(project.getBasedir(), tempLibrariesLocation);
			}
		} catch (IOException e) {
			//Ignore
		}
		return result;
	}
	
	protected void writeOriginalPOM() throws IOException {
		writeOriginalPOM(project.getFile());
	}

	protected void writeOriginalPOM(File destination) throws IOException {
		project.writeOriginalModel(new FileWriter(destination));
	}
	
	protected void writePOM() throws IOException {
		writePOM(project.getFile());
	}
	
	protected void writePOM(File destination) throws IOException {		
		project.writeModel(new FileWriter(destination));
	}
	
}
